<?php

namespace App\Exceptions;

use App\Common\Traits\ApiResponse;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class ExceptionReport
{
    use ApiResponse;

    protected $exception;
    protected $request;
    protected $report;

    /**
     * ExceptionReport constructor.
     * @param Request $request
     * @param Exception $exception
     */
    function __construct(Request $request, Exception $exception)
    {
        $this->request = $request;
        $this->exception = $exception;
    }

    protected function doReport()
    {
        $this->exception instanceof ValidationException ? $validateMsg = current(current($this->exception->errors())) : $validateMsg = '';
        return [
            AuthenticationException::class => ['token已过期，请重新登录', 401],
            ModelNotFoundException::class => ['请求的资源不存在', 404],
            ValidationException::class => [$validateMsg, 422],
            MethodNotAllowedHttpException::class => ['请求类型不正确', 405],
            UnauthorizedHttpException::class=> ['账号验证未通过', 401],
        ];
    }

    /**
     * @return bool
     */
    public function shouldReturn()
    {
        if (!($this->request->wantsJson() || $this->request->ajax())) {
            return false;
        }
        foreach (array_keys($this->doReport()) as $report) {

            if ($this->exception instanceof $report) {
                $this->report = $report;
                return true;
            }
        }

        return false;
    }

    /**
     * @param Exception $e
     * @return static
     */
    public static function make(Exception $e)
    {
        return new static(\request(), $e);
    }

    /**
     * @return mixed
     */
    public function report()
    {
        $message = $this->doReport()[$this->report];
        return $this->failed($message[0], $message[1]);
    }
}